# Create your tests here.
from pprint import pprint
from random import randint

from django.test import RequestFactory, TestCase, Client
from rest_framework import status

from unittest.mock import MagicMock, patch

import json

from jqgame.basegame import GameType
from jqpackage.models import UserPackageGoods
from juqiadmin.models import (
    update_finnce_profit,
    get_game_finance,
    get_wxuser_finance,
    GameRule,
)
from juqiadmin.serializers import UserPackageDetailedSerializer, GameRuleSerializer
from quanjushang.models import QuanjushangGame, QuanjushangSonGame
from warehouse.models import JuqiGood
from warehouse.serializers import JuqiGoodSerializer
from wuxianshang.models import WuxianshangGame
from wxcloudrun.models import get_web_settings
from wxcloudrun.views import order_uuid
from yifanshang.models import YifanshangGame

# from .views import wxuser
from .models import (
    OrderState,
    Users,
    UserRechargeOrder,
    UserStoredMoneyRecord,
    UserHunJingRecord,
    UserScoreRecord,
    UserOrder,
)


class UserTest(TestCase):
    def setUp(self):
        # Every test needs access to the request factory.
        self.c = Client(HTTP_X_WX_OPENID="wx123")
        self.factory = RequestFactory()

    @classmethod
    def create_a_user(cls):
        d = {
            "nickname": "xiaoming",
            "head_url": "http://nick",
            "openid": "wx123",
            "stored_money": int(1e8),
            "score": 0,
        }
        u = Users(**d)
        u.save()
        return u

    def req_create_user(self, nickname, head_url):
        r = self.c.post(
            "/api/wxuser/",
            {"nickname": nickname, "head_url": head_url},
            content_type="application/json",
        )
        return r

    def update_user(self, **kwargs):
        r = self.c.put(
            "/api/wxuser/",
            kwargs,
            content_type="application/json",
        )
        return r

    def query_user(self):
        r = self.c.get("/api/wxuser/")
        return r

    def test_req_create_user(self):
        # Create an instance of a POST request.
        r = self.req_create_user("123", "12345")
        d = json.loads(r.content)

        # success create user
        self.assertEqual(r.status_code, status.HTTP_201_CREATED)
        self.assertEqual(d["openid"], "wx123")
        self.assertEqual(d["nickname"], "123")
        self.assertEqual(d["head_url"], "12345")
        self.assertEqual(d["stored_money"], 0)
        self.assertEqual(d["score"], 0)

        # repeate create user
        r = self.req_create_user("123", "12345")
        self.assertEqual(r.status_code, status.HTTP_400_BAD_REQUEST)

    def test_query_uesr(self):
        r = self.req_create_user("123", "12345")
        self.assertEqual(r.status_code, status.HTTP_201_CREATED)

        r = self.query_user()
        self.assertEqual(r.status_code, status.HTTP_200_OK)

        d = json.loads(r.content)
        self.assertEqual(d["openid"], "wx123")
        self.assertEqual(d["nickname"], "123")
        self.assertEqual(d["head_url"], "12345")
        self.assertEqual(d["stored_money"], 0)
        self.assertEqual(d["score"], 0)

    def test_add_user_realname(self):
        r = self.req_create_user("123", "12345")
        self.assertEqual(r.status_code, status.HTTP_201_CREATED)

        data = {
            "realname": "xiaoming",
            "idcard_num": "100200",
        }

        r = self.update_user(**data)
        self.assertEqual(r.status_code, status.HTTP_200_OK)

        r = self.query_user()
        self.assertEqual(r.status_code, status.HTTP_200_OK)

        d = json.loads(r.content)
        self.assertEqual(d["realname"], "xiaoming")
        self.assertEqual(d["idcard_num"], "100200")

    # python manage.py test wxuser.tests.UserTest.test_request_user_telephone
    def test_request_user_telephone(self):
        UserTest.create_a_user()
        with patch("requests.post") as _post:
            res = MagicMock()
            _post.return_value = res
            res.content = json.dumps(
                {
                    "errcode": 0,
                    "errmsg": "ok",
                    "data_list": [
                        {
                            "cloud_id": "64_TKtVMk1uD4dj6OT45IEpk5v6LIIhsSqT_RssL9UsS1EuyctBiW6FbTU4-xI",
                            "json": '{ "cloudID":"64_TKtVMk1uD4dj6OT45IEpk5v6LIIhsSqT_RssL9UsS1EuyctBiW6FbTU4-xI", "data":{"phoneNumber":"18231129677","purePhoneNumber":"18231129677","countryCode":"86","watermark":{"timestamp":1674004393,"appid":"wx78a54c02662a91d5"}} }',
                        }
                    ],
                }
            )
            r = self.c.post(
                "/api/wxuser/telephone",
                {"cloudID": "1"},
                content_type="application/json",
            )
            d = json.loads(r.content)
            self.assertEqual(d["telephone"], "18231129677")

    def test_user_pay(self):
        r = self.req_create_user("123", "12345")
        self.assertEqual(r.status_code, status.HTTP_201_CREATED)
        # todo


class UserRechargeTest(TestCase):
    def setUp(self):
        # Every test needs access to the request factory.
        self.c = Client(
            HTTP_X_WX_OPENID="wx123",
            HTTP_X_FORWARDED_FOR="1",
            HTTP_X_WX_ENV="2",
            HTTP_X_WX_SERVICE="3",
        )
        self.factory = RequestFactory()

    def test_user_pay_1(self):
        u = UserTest.create_a_user()
        old_stored_money = u.stored_money

        # gen pay order
        prepay_params = {"total_fee": 99}
        for pay_count in range(1, 101):
            with patch("requests.post") as _wxapi_unifiedorder:
                data = {"respdata": {"payment": "1"}, "errcode": 0}

                m = MagicMock()
                m.content = json.dumps(data)

                _wxapi_unifiedorder.return_value = m

                r = self.c.put(
                    "/api/wxuser/pay/",
                    prepay_params,
                    content_type="application/json",
                )
                d = json.loads(r.content)
                self.assertEqual(d["code"], 0)
                self.assertEqual(d["payment"], data["respdata"]["payment"])

                uro = UserRechargeOrder.objects.get(out_trade_no=d["out_trade_no"])
                self.assertEqual(uro.total_fee, prepay_params["total_fee"])
                self.assertEqual(uro.state, OrderState.wait.value)

            # test callback
            pay_callback_params = {
                "resultCode": "SUCCESS",
                "subOpenid": "wx123",
                "totalFee": prepay_params["total_fee"],
                "outTradeNo": uro.out_trade_no,
            }
            r = self.c.post(
                "/api/wxuser/pay_callback/",
                pay_callback_params,
                content_type="application/json",
            )
            u = Users.objects.get(openid="wx123")
            self.assertEqual(
                u.stored_money,
                old_stored_money + prepay_params["total_fee"] * pay_count,
            )
            uro = UserRechargeOrder.objects.get(out_trade_no=d["out_trade_no"])

            self.assertEqual(uro.state, OrderState.success.value)

            r = self.c.get(
                f"/api/wxuser/pay/?out_trade_no={uro.out_trade_no}",
                content_type="application/json",
            )
            d = json.loads(r.content)
            self.assertEqual(d["total_fee"], prepay_params["total_fee"])
            self.assertEqual(d["state"], OrderState.success.value)
            self.assertEqual(d["out_trade_no"], uro.out_trade_no)

        # prepay_params = {"total_fee": 99}
        r = self.c.get(
            "/api/wxuser/pay/?list=1&page=1&num=50",
            content_type="application/json",
        )
        d = json.loads(r.content)
        self.assertEqual(len(d), 50)
        self.assertEqual(d[0]["total_fee"], prepay_params["total_fee"])
        self.assertEqual(d[0]["state"], OrderState.success.value)


# python manage.py test  wxuser.tests.UserWealthRecordTest
class UserWealthRecordTest(TestCase):
    def setUp(self):
        # Every test needs access to the request factory.
        self.c = Client(
            HTTP_X_WX_OPENID="wx123",
            HTTP_X_FORWARDED_FOR="1",
            HTTP_X_WX_ENV="2",
            HTTP_X_WX_SERVICE="3",
        )
        self.factory = RequestFactory()
        self.user = gen_user()
        self.wx_c = Client(HTTP_X_WX_OPENID=self.user.openid)

    def test_query_user_UserStoredMoneyRecord_1(self):
        u = UserTest.create_a_user()
        d = {
            "user_uuid": u.uuid,
            "stored_money": 99,
            "old_stored_money": 100,
            "new_stored_money": 199,
        }
        UserStoredMoneyRecord(**d).save()

        r = self.c.get(
            "/api/wxuser/userwealthrecord?list=1&page=1&num=50&query_type=stored_money"
        )
        d = json.loads(r.content)
        self.assertEqual(r.status_code, status.HTTP_200_OK)
        self.assertEqual(d[0]["user_uuid"], str(u.uuid))
        self.assertEqual(d[0]["stored_money"], 99)
        self.assertEqual(d[0]["old_stored_money"], 100)
        self.assertEqual(d[0]["new_stored_money"], 199)

    def test_query_user_UserHunJingRecord_1(self):
        u = UserTest.create_a_user()
        d = {
            "user_uuid": u.uuid,
            "hunjing": 99,
            "old_hunjing": 100,
            "new_hunjing": 199,
        }
        UserHunJingRecord(**d).save()

        r = self.c.get(
            "/api/wxuser/userwealthrecord?list=1&page=1&num=50&query_type=hunjing"
        )
        d = json.loads(r.content)
        self.assertEqual(r.status_code, status.HTTP_200_OK)
        self.assertEqual(d[0]["user_uuid"], str(u.uuid))
        self.assertEqual(d[0]["hunjing"], 99)
        self.assertEqual(d[0]["old_hunjing"], 100)
        self.assertEqual(d[0]["new_hunjing"], 199)

    def test_query_user_UserScoreRecord_1(self):
        u = UserTest.create_a_user()
        d = {
            "user_uuid": u.uuid,
            "score": 99,
            "old_score": 100,
            "new_score": 199,
        }
        UserScoreRecord(**d).save()

        r = self.c.get(
            "/api/wxuser/userwealthrecord?list=1&page=1&num=50&query_type=score"
        )
        d = json.loads(r.content)
        self.assertEqual(r.status_code, status.HTTP_200_OK)
        self.assertEqual(d[0]["user_uuid"], str(u.uuid))
        self.assertEqual(d[0]["score"], 99)
        self.assertEqual(d[0]["old_score"], 100)
        self.assertEqual(d[0]["new_score"], 199)

    def test_query_games(self):
        for i in range(10):
            QuanjushangGame(
                name="全局赏" + str(i),
                state=1,
                game_num=(i + 1) * 10,
                price=(i + 1) * 1000,
                cover_url="https://",
                score_pay=randint(0, 1),
                hide_stats=1,
            ).save()
            WuxianshangGame(
                name="无限赏" + str(i),
                state=1,
                count=(i + 1) * 10,
                price=(i + 1) * 1000,
                display_url="https://",
                score_pay=randint(0, 1),
                baodi=1,
                tianjiangsb=1,
                feiqiu=1,
            ).save()
            YifanshangGame(
                name="一番赏" + str(i),
                state=1,
                game_num=(i + 1) * 10,
                price=(i + 1) * 1000,
                cover_url="https://",
                is_hide=1,
            ).save()

        # r = self.wx_c.get("/api/wxuser/game")
        # _data = json.loads(r.content)
        # pprint(_data)
        # r = self.wx_c.get(
        #     "/api/wxuser/game?game_type=" + str(GameType.wuxianshang.value)
        # )
        # _data = json.loads(r.content)
        # pprint(_data)
        # r = self.wx_c.get(
        #     "/api/wxuser/game?game_type=" + str(GameType.quanjushang.value)
        # )
        # _data = json.loads(r.content)
        # pprint(_data)
        # r = self.wx_c.get(
        #     "/api/wxuser/game?game_type=" + str(GameType.yifanshang.value)
        # )
        # _data = json.loads(r.content)
        # pprint(_data)
        # r = self.wx_c.get("/api/wxuser/game", {"wanfa": 1})
        # _data = json.loads(r.content)
        # pprint(_data)
        #
        # r = self.wx_c.get("/api/wxuser/game", {"wanfa": 2})
        # _data = json.loads(r.content)
        # pprint(_data)
        # r = self.wx_c.get("/api/wxuser/game", {"wanfa": 3})
        # _data = json.loads(r.content)
        # pprint(_data)
        r = self.wx_c.get("/api/wxuser/game", {"wanfa": 4})
        _data = json.loads(r.content)
        pprint(_data)
        c = Client(HTTP_X_WX_OPENID="1212")
        r = c.get("/api/wxuser/game", {"wanfa": 2})
        _data = json.loads(r.content)
        pprint(_data)
        # r = c.get("/api/wxuser/game", {"wanfa": 3})
        # _data = json.loads(r.content)
        # pprint(_data)
        # r = c.get("/api/wxuser/game", {"wanfa": 4})
        # _data = json.loads(r.content)
        # pprint(_data)
        # game_rule = GameRule.objects.create(key="aabbcc", body="aaaaaa")
        # uuid = GameRuleSerializer(game_rule).data["uuid"]
        # r = self.wx_c.get("/api/wxuser/game/roule?uuid=" + uuid)
        # _data = json.loads(r.content)
        # pprint(_data)

    def test_query_wuxianshang_raffle(self):
        res = self.wx_c.get(
            "/api/wuxianshang/p/raffle/?offset=1&limit=8&game_uuid=fdb143fa-1993-4aee-83f3-df69dd7d2bd1&recoder_type=2"
        )
        data = json.loads(res.content)
        pprint(data)

    def test_user_history_recharge(self):
        create_orders()
        res = self.wx_c.get("/api/wxuser/history/recharge")
        data = json.loads(res.content)
        pprint(data)

    def test_user_history_refining(self):
        create_orders()
        goods_list = UserPackageGoods.objects.filter(user_uuid=self.user.uuid)
        goods_uuid_list = []
        for goods in goods_list:
            goods_data = UserPackageDetailedSerializer(goods).data
            goods_uuid_list.append(goods_data["uuid"])
        # pprint(goods_uuid_list)

        good_list = JuqiGood.objects.filter(deleted=False)
        good_uuid_list = []

        for good in good_list:
            good_data = JuqiGoodSerializer(good).data
            good_uuid_list.append({"uuid": good_data["uuid"], "count": 10})
        pprint(good_uuid_list)
        # res = self.wx_c.put(
        #     "/api/package/refined",
        #     {"goods": goods_uuid_list},
        #     content_type="application/json",
        # )
        # data = json.loads(res.content)
        # pprint(data)

        res = self.wx_c.put(
            "/api/package/refined",
            {"goods": good_uuid_list, "display": 1},
            content_type="application/json",
        )
        data = json.loads(res.content)
        pprint(data)

        res = self.wx_c.get("/api/wxuser/history/refining")
        data = json.loads(res.content)
        pprint(data)

    def test_user_wealthrecord(self):
        create_goods()
        create_orders()
        res = self.wx_c.get(
            "/api/wxuser/userwealthrecord",
            {"list": 1, "query_type": "stored_money", "record_type": 1},
        )
        data = json.loads(res.content)
        pprint(data)


def gen_user():
    for i in range(10):
        Users.objects.create(
            openid="12121212121212121211212" + str(i),
            nickname="admin_" + str(i),
            realname="cc" + str(i),
            telephone="11111111111" + str(i),
            need_help=True,
            stored_money=randint(1000, 10000),
            score=randint(1000, 10000),
            hunjing=randint(10000, 1000000000),
        )

    return Users.objects.create(
        openid="12121212121212121211212",
        nickname="admin_a",
        realname="cc",
        telephone="11111111111",
        need_help=True,
        is_real=True,
        stored_money=int(1e8),
        score=int(1e8),
        hunjing=int(1e8),
    )


def create_goods():
    for i in range(5):
        JuqiGood(
            name="小汽车" + str(randint(100, 10000)),
            display_url="123" + str(randint(100, 10000)),
            price=50 + randint(100, 1000),
            recovery_price=10 + randint(0, 100),
            game_type="全局赏",
            level_title="A赏品",
            ip_family="123" + str(randint(100, 10000)),
            # 商品详细介绍
            detail="123" + str(randint(100, 10000)),
        ).save()


def create_orders():
    create_goods()
    users = Users.objects.filter(deleted=False).all()
    goods = JuqiGood.objects.filter(deleted=False).all()
    set = get_web_settings()
    set.statistical_exclude_user_id = "1,2,3"
    set.save()
    game = QuanjushangGame.objects.create(
        name="test池子", cover_url="123", user_limit=1, price=10, game_num=50
    )
    son_game_ = []
    for v in range(1, 5 + 1):
        i = {"game_uuid": game.uuid, "user_limit": 1, "price": 1000, "box_num": v}
        son_game_.append(QuanjushangSonGame(**i))
    son_games = QuanjushangSonGame.objects.bulk_create(son_game_)

    for user in users:
        for son_game in son_games:
            user_order = UserOrder.objects.create(
                user_uuid=user.uuid,
                game_type=GameType.quanjushang.value,
                game_uuid=game.uuid,
                game_name=game.name,
                son_uuid=son_game.uuid,
                box_num=son_game.box_num,
                num=game.game_num,
                money=game.price,
                price=game.price,
                hunjing=0,
                score=0,
                weixin=0,
                orderid=order_uuid("CS_"),
            )
            for good in goods:
                for i in range(randint(1, 5)):
                    UserPackageGoods(
                        order_uuid=user_order.uuid,
                        good_uuid=good.uuid,
                        user_uuid=user.uuid,
                        good_level_title="A赏品",
                        game_type=GameType.quanjushang.value,
                        game_uuid=game.uuid,
                        game_son_uuid=son_game.uuid,
                        game_box_num=son_game.box_num,
                        order_num=i,
                    ).save()
                    finance = get_wxuser_finance(
                        GameType.quanjushang, user.uuid, game.uuid
                    )
                    finance_game = get_game_finance(gameType=GameType.quanjushang)
                    _all_raffle_income = randint(10000, 1000000)
                    _all_raffle_cost = randint(10, 10000)
                    finance.all_raffle_income += _all_raffle_income
                    finance.all_raffle_cost += _all_raffle_cost
                    finance_game.all_raffle_income += _all_raffle_income
                    finance_game.all_raffle_cost += _all_raffle_cost
                    update_finnce_profit(finance)
                    update_finnce_profit(finance_game)
                    finance.save()
                    finance_game.save()
